from flask import request
from flask_restx import Resource, Namespace, fields
from app.utils.response import success_response, error_response, paginate_response
from app.utils.auth import token_required
from app.utils.validators import validate_required_fields
from app.services.menu_service import MenuService
from app.swagger_docs import (
    success_response_model, error_response_model, pagination_response_model,
    menu_model
)

# 创建菜单命名空间
menu_ns = Namespace('menus', description='菜单管理接口')

# 定义请求模型
menu_create_model = menu_ns.model('MenuCreate', {
    'name': fields.String(required=True, description='菜单名称'),
    'path': fields.String(description='菜单路径'),
    'component': fields.String(description='组件路径'),
    'icon': fields.String(description='菜单图标'),
    'parent_id': fields.Integer(description='父级菜单ID'),
    'sort': fields.Integer(description='排序', default=0),
    'visible': fields.Boolean(description='是否可见', default=True),
    'type': fields.String(description='菜单类型 (menu:菜单, button:按钮)', default='menu'),
    'permission': fields.String(description='权限标识')
})

menu_update_model = menu_ns.model('MenuUpdate', {
    'name': fields.String(description='菜单名称'),
    'path': fields.String(description='菜单路径'),
    'component': fields.String(description='组件路径'),
    'icon': fields.String(description='菜单图标'),
    'parent_id': fields.Integer(description='父级菜单ID'),
    'sort': fields.Integer(description='排序'),
    'visible': fields.Boolean(description='是否可见'),
    'type': fields.String(description='菜单类型'),
    'permission': fields.String(description='权限标识')
})

@menu_ns.route('/')
class MenuListAPI(Resource):
    """菜单列表和新增接口"""
    
    @menu_ns.doc(
        description='获取菜单列表（支持树形结构）',
        security='Bearer',
        params={
            'tree': '是否返回树形结构 (true/false)',
            'page': '页码（非树形结构时使用）',
            'per_page': '每页数量（非树形结构时使用）',
            'keyword': '搜索关键词',
            'visible': '可见性筛选 (0:隐藏, 1:显示)',
            'status': '状态筛选 (0:禁用, 1:启用)'
        },
        responses={
            200: ('获取成功', success_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def get(self, **kwargs):
        """获取菜单列表"""
        current_admin = kwargs.get('current_admin')
        # 检查是否需要树形结构
        tree = request.args.get('tree', type=bool)
        
        # 获取筛选参数
        keyword = request.args.get('keyword', '')
        visible = request.args.get('visible', type=int)
        status = request.args.get('status', type=int)
        
        if visible is not None:
            visible = bool(visible)
        if status is not None:
            status = bool(status)
        
        if tree:
            # 根据用户角色获取菜单
            if current_admin and current_admin.role_id:
                # 检查是否为超级管理员角色（通常role_id=1为超级管理员）
                if current_admin.role_id == 1:
                    # 超级管理员返回所有菜单（支持筛选）
                    data = MenuService.get_tree(keyword=keyword or None, visible=visible, status=status)
                else:
                    # 其他角色根据权限返回菜单
                    data = MenuService.get_tree_by_role(current_admin.role_id)
            else:
                # 没有角色信息时返回空
                data = []
            return success_response(data)
        
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        
        query, page, per_page = MenuService.get_list(page, per_page, keyword, visible, status)
        return paginate_response(query, page, per_page)
    
    @menu_ns.doc(
        description='创建新菜单',
        security='Bearer',
        responses={
            200: ('创建成功', success_response_model),
            400: ('请求参数错误', error_response_model),
            401: ('未授权', error_response_model),
            500: ('服务器错误', error_response_model)
        }
    )
    @menu_ns.expect(menu_create_model, validate=True)
    @token_required
    def post(self, **kwargs):
        """创建新菜单"""
        current_admin = kwargs.get('current_admin')
        # 验证必填字段
        is_valid, error_msg = validate_required_fields(['name'])
        if not is_valid:
            return error_response(error_msg, 400)
        
        data = request.get_json()
        
        try:
            menu = MenuService.create(data)
            return success_response(menu.to_dict(), '创建成功')
        except Exception as e:
            return error_response(f'创建失败：{str(e)}', 500)


@menu_ns.route('/<int:menu_id>')
class MenuDetailAPI(Resource):
    """菜单详情、更新和删除接口"""
    
    @menu_ns.doc(
        description='获取菜单详情',
        security='Bearer',
        responses={
            200: ('获取成功', success_response_model),
            404: ('菜单不存在', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def get(self, menu_id, **kwargs):
        """获取菜单详情"""
        current_admin = kwargs.get('current_admin')
        menu = MenuService.get_by_id(menu_id)
        if not menu:
            return error_response('菜单不存在', 404)
        
        return success_response(menu.to_dict())
    
    @menu_ns.doc(
        description='更新菜单信息',
        security='Bearer',
        responses={
            200: ('更新成功', success_response_model),
            400: ('请求参数错误', error_response_model),
            404: ('菜单不存在', error_response_model),
            401: ('未授权', error_response_model),
            500: ('服务器错误', error_response_model)
        }
    )
    @menu_ns.expect(menu_update_model)
    @token_required
    def put(self, menu_id, **kwargs):
        """更新菜单信息"""
        current_admin = kwargs.get('current_admin')
        menu = MenuService.get_by_id(menu_id)
        if not menu:
            return error_response('菜单不存在', 404)
        
        data = request.get_json()
        
        try:
            updated_menu = MenuService.update(menu_id, data)
            return success_response(updated_menu.to_dict(), '更新成功')
        except Exception as e:
            return error_response(f'更新失败：{str(e)}', 500)
    
    @menu_ns.doc(
        description='删除菜单',
        security='Bearer',
        responses={
            200: ('删除成功', success_response_model),
            400: ('删除失败', error_response_model),
            404: ('菜单不存在', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def delete(self, menu_id, **kwargs):
        """删除菜单"""
        current_admin = kwargs.get('current_admin')
        result = MenuService.delete(menu_id)
        if isinstance(result, tuple):
            success, message = result
            if not success:
                return error_response(message, 400)
            return success_response(message=message)
        else:
            if not result:
                return error_response('删除失败，菜单不存在', 404)
            return success_response(message='删除成功')


@menu_ns.route('/options')
class MenuOptionsAPI(Resource):
    """菜单选项数据接口"""
    
    @menu_ns.doc(
        description='获取菜单选项数据（用于创建子菜单时选择父菜单）',
        security='Bearer',
        responses={
            200: ('获取成功', success_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def get(self, **kwargs):
        """获取菜单选项数据"""
        current_admin = kwargs.get('current_admin')
        data = MenuService.get_parent_options()
        return success_response(data) 